//
//  AddBookView.swift
//  KoiAccounting
//
//  Created by 纪洪文 on 03.04.25.
//

import SwiftUI

struct AddBookView: View {
    
    @Environment(\.presentToast) var presentToast
    @Environment(\.presentationMode) var presentationMode
    
    @StateObject var viewModel = AddBookViewModel()
    
    private let bookNameLimit = 12
    @State private var inputBookName:String = ""
    @State private var inputBookRemark:String = ""
    @State private var selectedColor:String = "#EF443A"
    @State private var showColorSelectDiaog = false
    
    var body: some View {
        VStack {
            HStack {
                Button(action: {
                    showColorSelectDiaog = true
                }) {
                    ZStack {
                        Image("koi_ic_wallet_highlight")
                            .renderingMode(.template)
                            .resizable().frame(width: 16, height: 16)
                            .foregroundColor(Color(hex: selectedColor))
                        Image("koi_ic_wallet").resizable().frame(width: 24, height: 24)
                    }
                }
                
                TextFieldWithLimit(placeholder: "请输入账本名称", text: $inputBookName, characterLimit: bookNameLimit)
                    .font(.system(size: 14))
                    .bold()
                    .foregroundColor(Color.koiColorTitle)
            }
            .padding(EdgeInsets(top: 20, leading: 16, bottom: 20, trailing: 16))
            .background(Color.koiColorBackgroundItem)
            .cornerRadius(16)
            .padding(.top, 10)
            
            HStack {
                TextFieldWithLimit(placeholder: "账本备注（可选）", text: $inputBookRemark, characterLimit: 100)
                    .font(.system(size: 14))
                    .bold()
                    .foregroundColor(Color.koiColorTitle)
            }
            .padding(EdgeInsets(top: 20, leading: 16, bottom: 20, trailing: 16))
            .background(Color.koiColorBackgroundItem)
            .cornerRadius(16)
            .padding(.top, 20)
            
            Button(action: {
                saveBook()
            }) {
                Text("完成")
                    .font(.system(size: 15))
                    .bold()
                    .foregroundColor(Color.white)
                    .frame(maxWidth: .infinity)
                    .padding(EdgeInsets(top: 15, leading: 0, bottom: 15, trailing: 0))
                    .background(Color.koiColorPrimary)
                    .cornerRadius(40)
                    .padding(.top, 20)
            }
            
            Spacer()
        }.padding(.horizontal, 20)
            .koiToolbar(title: Text("新增账本"))
        .navigationBarTitle(Text("新增账本"), displayMode: .inline)
        .sheet(isPresented: $showColorSelectDiaog) {
            AddBookColorSelectView(selectedColor:$selectedColor).presentationDetents([.medium])
        }
        .onChange(of: viewModel.saveState) { newValue in
            if (newValue == "success") {
                viewModel.saveState = ""
                presentToast(.init(message: "新增账本成功"))
                presentationMode.wrappedValue.dismiss()
            }
        }
        .background(Color.koiColorBackground)
    }
    
    private func saveBook() {
        if (inputBookName.isEmpty) {
            presentToast(.init(message: "请输入账本名称"))
            return
        }
        var bookRemark:String? = nil
        if (!inputBookRemark.isEmpty) {
            bookRemark = inputBookRemark
        }
        viewModel.save(bookName:inputBookName, bookColor: selectedColor, bookRemark: bookRemark)
    }
}

struct TextFieldWithLimit: UIViewRepresentable {
    var placeholder: String
    @Binding var text: String
    var characterLimit: Int
    var font: UIFont = .systemFont(ofSize: 14)

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIView(context: Context) -> UITextField {
        let textField = UITextField()
        //textField.placeholder = placeholder
        textField.textColor = UIColor(Color.koiColorTitle)
        textField.attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [NSAttributedString.Key.foregroundColor: UIColor(Color.koiColorTitleSecond)])
        textField.delegate = context.coordinator
        textField.setContentHuggingPriority(.required, for: .vertical)
        textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
        textField.borderStyle = .none
        textField.clearButtonMode = .whileEditing
        textField.addTarget(context.coordinator, action: #selector(Coordinator.textFieldDidChange), for: .editingChanged)
        return textField
    }

    func updateUIView(_ uiView: UITextField, context: Context) {
        uiView.text = text
        uiView.font = font
    }

    class Coordinator: NSObject, UITextFieldDelegate {
        var parent: TextFieldWithLimit

        init(_ parent: TextFieldWithLimit) {
            self.parent = parent
        }

        @objc func textFieldDidChange(_ textField: UITextField) {
            if let markedTextRange = textField.markedTextRange, textField.position(from: markedTextRange.start, offset: 0) != nil {
                // If there is marked text (e.g., during pinyin input), do nothing
                return
            }
            // Otherwise, truncate the text if it exceeds the character limit
            if textField.text?.count ?? 0 > parent.characterLimit {
                textField.text = String(textField.text?.prefix(parent.characterLimit) ?? "")
            }
            parent.text = textField.text ?? ""
        }

        func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
            let currentText = textField.text ?? ""
            guard let stringRange = Range(range, in: currentText) else {
                return false
            }
            let updatedText = currentText.replacingCharacters(in: stringRange, with: string)
            // Allow change if the text is within the character limit or it's marked text
            return updatedText.count <= parent.characterLimit || textField.markedTextRange != nil
        }
    }
}

#Preview {
    AddBookView()
}
